<!--
 * 字典类型新增/编辑表单页面
 * 基于蒜苔系统字典管理设计文档重写，提供完整的表单功能和验证
 -->

<template>
  <a-modal
    v-model:open="visible"
    :title="isEdit ? '编辑字典类型' : '新增字典类型'"
    width="600px"
    :mask-closable="false"
    :confirmLoading="loading"
    @ok="handleSubmit"
    @cancel="handleCancel"
  >
    <a-form
      ref="formRef"
      :model="formData"
      :rules="formRules"
      :label-col="{ span: 6 }"
      :wrapper-col="{ span: 18 }"
    >
      <a-form-item label="字典名称" name="dictName">
        <a-input
          v-model:value="formData.dictName"
          placeholder="请输入字典名称，如：用户状态"
          :maxlength="100"
          show-count
        />
      </a-form-item>

      <a-form-item label="字典类型" name="dictType">
        <a-input
          v-model:value="formData.dictType"
          placeholder="请输入字典类型标识，如：user_status"
          :maxlength="100"
          show-count
          :disabled="isEdit"
        >
          <template #addonBefore>
            <CodeOutlined />
          </template>
        </a-input>
        <div class="form-help-text">
          字典类型标识用于程序调用，建议使用英文和下划线，创建后不可修改
        </div>
      </a-form-item>

      <a-form-item label="字典描述" name="dictDesc">
        <a-textarea
          v-model:value="formData.dictDesc"
          placeholder="请输入字典描述，说明该字典的用途和包含的数据类型"
          :maxlength="500"
          :rows="3"
          show-count
        />
      </a-form-item>

      <a-form-item label="状态" name="status">
        <a-radio-group v-model:value="formData.status">
          <a-radio :value="1">
            <a-tag color="success">启用</a-tag>
            <span style="margin-left: 8px;">字典类型启用后可以正常使用</span>
          </a-radio>
          <a-radio :value="0">
            <a-tag color="error">禁用</a-tag>
            <span style="margin-left: 8px;">字典类型禁用后将不可使用</span>
          </a-radio>
        </a-radio-group>
      </a-form-item>

      <a-form-item label="排序序号" name="sortOrder">
        <a-input-number
          v-model:value="formData.sortOrder"
          placeholder="请输入排序序号"
          :min="0"
          :max="9999"
          style="width: 200px"
        />
        <div class="form-help-text">
          数值越小排序越靠前，相同数值按创建时间排序
        </div>
      </a-form-item>

      <!-- 编辑模式下显示系统信息 -->
      <template v-if="isEdit && formData.isSystem === 1">
        <a-form-item label="系统内置">
          <a-tag color="orange">
            <SafetyCertificateOutlined />
            系统内置字典类型
          </a-tag>
          <div class="form-help-text">
            系统内置字典类型由系统自动创建，部分操作可能受限
          </div>
        </a-form-item>
      </template>

      <!-- 预览区域 -->
      <a-form-item label="预览效果">
        <div class="preview-section">
          <div class="preview-item">
            <span class="preview-label">字典名称：</span>
            <span class="preview-value">{{ formData.dictName || '未填写' }}</span>
          </div>
          <div class="preview-item">
            <span class="preview-label">字典类型：</span>
            <a-tag color="blue">{{ formData.dictType || '未填写' }}</a-tag>
          </div>
          <div class="preview-item">
            <span class="preview-label">状态：</span>
            <a-tag :color="formData.status === 1 ? 'success' : 'error'">
              {{ formData.status === 1 ? '启用' : '禁用' }}
            </a-tag>
          </div>
          <div class="preview-item">
            <span class="preview-label">排序：</span>
            <span class="preview-value">{{ formData.sortOrder }}</span>
          </div>
        </div>
      </a-form-item>
    </a-form>
  </a-modal>
</template>

<script lang="ts" setup>
import { ref, reactive, computed, nextTick } from 'vue';
import { message } from 'ant-design-vue';
import { CodeOutlined, SafetyCertificateOutlined } from '@ant-design/icons-vue';
import type { FormInstance, Rule } from 'ant-design-vue/es/form';
import type { SysDictType } from './types';
import { apiSysDictTypeAdd, apiSysDictTypeEdit, apiSysDictTypeFetchDetail } from './api';
import { getMockSysDictTypeData } from './mock';

// 组件属性
interface Props {
  callbackFunc?: () => void;
}

const props = withDefaults(defineProps<Props>(), {
  callbackFunc: () => {}
});

// 响应式数据
const visible = ref(false);
const loading = ref(false);
const isEdit = ref(false);
const formRef = ref<FormInstance>();

// 表单数据
const formData = reactive<Partial<SysDictType>>({
  dictName: '',
  dictType: '',
  dictDesc: '',
  status: 1,
  sortOrder: 0,
  isSystem: 0
});

// 表单验证规则
const formRules = computed<Record<string, Rule[]>>(() => ({
  dictName: [
    { required: true, message: '字典名称不能为空', trigger: 'blur' },
    { max: 100, message: '字典名称长度不能超过100个字符', trigger: 'blur' }
  ],
  dictType: [
    { required: true, message: '字典类型标识不能为空', trigger: 'blur' },
    { max: 100, message: '字典类型标识长度不能超过100个字符', trigger: 'blur' },
    { 
      pattern: /^[a-zA-Z][a-zA-Z0-9_]*$/, 
      message: '字典类型标识必须以字母开头，只能包含字母、数字和下划线', 
      trigger: 'blur' 
    },
    { validator: validateDictTypeUnique, trigger: 'blur' }
  ],
  dictDesc: [
    { max: 500, message: '字典描述长度不能超过500个字符', trigger: 'blur' }
  ],
  status: [
    { required: true, message: '请选择状态', trigger: 'change' }
  ],
  sortOrder: [
    { type: 'number', min: 0, max: 9999, message: '排序序号必须在0-9999之间', trigger: 'blur' }
  ]
}));

// 验证字典类型标识唯一性
async function validateDictTypeUnique(rule: Rule, value: string) {
  if (!value || isEdit.value) {
    return Promise.resolve();
  }
  
  try {
    // 获取现有数据检查唯一性
    const mockDataResult = getMockSysDictTypeData({ pageSize: 1000 }); // 获取所有数据
    const exists = mockDataResult.records.some(item => item.dictType === value);
    
    if (exists) {
      return Promise.reject('字典类型标识已存在');
    }
    
    return Promise.resolve();
  } catch (error) {
    console.error('验证字典类型唯一性失败:', error);
    return Promise.resolve(); // 验证失败时不阻止提交
  }
}

// 重置表单
function resetForm() {
  Object.assign(formData, {
    dictName: '',
    dictType: '',
    dictDesc: '',
    status: 1,
    sortOrder: 0,
    isSystem: 0
  });
  
  nextTick(() => {
    formRef.value?.clearValidate();
  });
}

// 显示新增表单
function showAdd() {
  isEdit.value = false;
  resetForm();
  visible.value = true;
}

// 显示编辑表单
async function showEdit(id: number) {
  isEdit.value = true;
  visible.value = true;
  loading.value = true;
  
  try {
    const response = await apiSysDictTypeFetchDetail(id);
    if (response.success && response.data) {
      Object.assign(formData, response.data);
    } else {
      message.error('获取字典类型详情失败');
      visible.value = false;
    }
  } catch (error) {
    console.error('获取字典类型详情失败:', error);
    message.error('获取字典类型详情失败');
    visible.value = false;
  } finally {
    loading.value = false;
  }
}

// 处理表单提交
async function handleSubmit() {
  try {
    await formRef.value?.validate();
    loading.value = true;
    
    const submitData = { ...formData };
    
    if (isEdit.value) {
      // 编辑模式
      const response = await apiSysDictTypeEdit(submitData as SysDictType);
      if (response.success) {
        message.success('编辑字典类型成功');
        visible.value = false;
        props.callbackFunc();
      } else {
        message.error(response.message || '编辑字典类型失败');
      }
    } else {
      // 新增模式
      const response = await apiSysDictTypeAdd(submitData as SysDictType);
      if (response.success) {
        message.success('新增字典类型成功');
        visible.value = false;
        props.callbackFunc();
      } else {
        message.error(response.message || '新增字典类型失败');
      }
    }
  } catch (error) {
    console.error('表单提交失败:', error);
    if (error && typeof error === 'object' && 'errorFields' in error) {
      // 表单验证失败
      const firstError = (error as any).errorFields?.[0];
      if (firstError?.errors?.[0]) {
        message.error(firstError.errors[0]);
      }
    } else {
      message.error('操作失败，请重试');
    }
  } finally {
    loading.value = false;
  }
}

// 处理取消
function handleCancel() {
  visible.value = false;
  resetForm();
}

// 暴露方法给父组件
defineExpose({
  showAdd,
  showEdit
});
</script>

<style scoped>
/* 表单帮助文本样式 */
.form-help-text {
  color: #999;
  font-size: 12px;
  margin-top: 4px;
  line-height: 1.4;
}

/* 预览区域样式 */
.preview-section {
  background: #fafafa;
  border: 1px solid #e8e8e8;
  border-radius: 6px;
  padding: 16px;
}

.preview-item {
  display: flex;
  align-items: center;
  margin-bottom: 8px;
}

.preview-item:last-child {
  margin-bottom: 0;
}

.preview-label {
  color: #666;
  font-size: 14px;
  min-width: 80px;
  margin-right: 8px;
}

.preview-value {
  color: #333;
  font-size: 14px;
}

/* 表单项样式优化 */
:deep(.ant-form-item-label) {
  font-weight: 500;
}

:deep(.ant-input-number) {
  width: 100%;
}

:deep(.ant-radio-group) {
  width: 100%;
}

:deep(.ant-radio) {
  display: flex;
  align-items: center;
  margin-bottom: 8px;
  padding: 8px 12px;
  border: 1px solid #e8e8e8;
  border-radius: 6px;
  transition: all 0.3s;
}

:deep(.ant-radio:hover) {
  border-color: #1890ff;
  background-color: #f0f8ff;
}

:deep(.ant-radio-checked) {
  border-color: #1890ff;
  background-color: #f0f8ff;
}

/* 状态标签样式 */
:deep(.ant-tag) {
  margin-right: 0;
}

/* 输入框前缀图标样式 */
:deep(.ant-input-group-addon) {
  background-color: #fafafa;
  border-color: #d9d9d9;
}

/* 字符计数样式 */
:deep(.ant-input-show-count-suffix) {
  color: #999;
}

:deep(.ant-textarea-show-count::after) {
  color: #999;
}

/* 表单验证错误样式 */
:deep(.ant-form-item-has-error .ant-input) {
  border-color: #ff4d4f;
}

:deep(.ant-form-item-has-error .ant-input:focus) {
  border-color: #ff4d4f;
  box-shadow: 0 0 0 2px rgba(255, 77, 79, 0.2);
}

/* 模态框样式优化 */
:deep(.ant-modal-header) {
  border-bottom: 1px solid #e8e8e8;
  padding: 16px 24px;
}

:deep(.ant-modal-title) {
  font-size: 16px;
  font-weight: 600;
  color: #333;
}

:deep(.ant-modal-body) {
  padding: 24px;
}

:deep(.ant-modal-footer) {
  border-top: 1px solid #e8e8e8;
  padding: 12px 24px;
}

/* 响应式设计 */
@media (max-width: 768px) {
  :deep(.ant-modal) {
    width: 95% !important;
    margin: 10px auto;
  }
  
  :deep(.ant-form-item-label) {
    text-align: left;
  }
  
  .preview-item {
    flex-direction: column;
    align-items: flex-start;
  }
  
  .preview-label {
    margin-bottom: 4px;
    margin-right: 0;
  }
}
</style>